package ejb;

import java.util.*;

import javax.ejb.Stateless;
import javax.naming.InitialContext;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import vo.ArticuloVO;
import vo.PendienteVO;
import vo.TiendaVO;
import entity.Articulo;
import entity.ArticuloEnviado;
import entity.ArticuloAFabricar;
import entity.Pendiente;
import entity.RegistroEnvio;
import entity.RegistroFabricacion;
import entity.Tienda;

@Stateless
public class AdministradorPendienteBean implements AdministradorPendiente
{
	@PersistenceContext(unitName = "pendientes")
	private EntityManager em;

	private AdministradorArticulo administradorArticulo;
	private AdministradorTienda administradorTienda;
	private AdministradorRegistroEnvios administradorRegistroEnvios;
	private AdministradorRegistroFabricacion administradorRegistroFabricacion;
	private AdministradorRegistroReposicion administradorRegistroReposicion;
	
	// AdministradorArticulo
	@SuppressWarnings("unchecked")
	void getAdministradorArticulo()
	{
        try
        {
			String naming = "AdministradorCDApp/AdministradorArticuloBean/local";
			Hashtable props = new Hashtable();
			InitialContext ic = new InitialContext(props);
			administradorArticulo = (AdministradorArticulo)ic.lookup(naming);
			
			if(administradorArticulo!=null)
			{
				System.out.println("Se logro conectar al bean de AdministradorArticulo");
			}
        }
        catch (Exception e)
        {
        	System.out.println("Error al conectarse al bean de AdministradorArticulo");
        	e.printStackTrace();
        }
    }
	
	// AdministradorTienda
	@SuppressWarnings("unchecked")
	void getAdministradorTienda()
	{
        try
        {
			String naming = "AdministradorCDApp/AdministradorTiendaBean/local";
			Hashtable props = new Hashtable();
			InitialContext ic = new InitialContext(props);
			administradorTienda = (AdministradorTienda)ic.lookup(naming);
			
			if(administradorTienda!=null)
			{
				System.out.println("Se logro conectar al bean de AdministradorTienda");
			}
        }
        catch (Exception e)
        {
        	System.out.println("Error al conectarse al bean de AdministradorTienda");
        	e.printStackTrace();
        }
    }

	// AdministradorRegistroEnvios
	@SuppressWarnings("unchecked")
	void getAdministradorRegistroEnvios()
	{
        try
        {
			String naming = "AdministradorCDApp/AdministradorRegistroEnviosBean/local";
			Hashtable props = new Hashtable();
			InitialContext ic = new InitialContext(props);
			administradorRegistroEnvios = (AdministradorRegistroEnvios)ic.lookup(naming);
			
			if(administradorRegistroEnvios!=null)
			{
				System.out.println("Se logro conectar al bean de AdministradorRegistroEnvios");
			}
        }
        catch (Exception e)
        {
        	System.out.println("Error al conectarse al bean de AdministradorRegistroEnvios");
        	e.printStackTrace();
        }
    }

	// AdministradorRegistroFabricacion
	@SuppressWarnings("unchecked")
	void getAdministradorRegistroFabricacion()
	{
        try
        {
			String naming = "AdministradorCDApp/AdministradorRegistroFabricacionBean/local";
			Hashtable props = new Hashtable();
			InitialContext ic = new InitialContext(props);
			administradorRegistroFabricacion = (AdministradorRegistroFabricacion)ic.lookup(naming);
			
			if(administradorRegistroFabricacion!=null)
			{
				System.out.println("Se logro conectar al bean de AdministradorRegistroFabricacion");
			}
        }
        catch (Exception e)
        {
        	System.out.println("Error al conectarse al bean de AdministradorRegistroFabricacion");
        	e.printStackTrace();
        }
    }

	// AdministradorRegistroReposicion
	@SuppressWarnings("unchecked")
	void getAdministradorRegistroReposicion()
	{
        try
        {
			String naming = "AdministradorCDApp/AdministradorRegistroReposicionBean/local";
			Hashtable props = new Hashtable();
			InitialContext ic = new InitialContext(props);
			administradorRegistroReposicion = (AdministradorRegistroReposicion)ic.lookup(naming);
			
			if(administradorRegistroReposicion!=null)
			{
				System.out.println("Se logro conectar al bean de AdministradorRegistroReposicion");
			}
        }
        catch (Exception e)
        {
        	System.out.println("Error al conectarse al bean de AdministradorRegistroReposicion");
        	e.printStackTrace();
        }
	}

	public void guardarPendiente(PendienteVO pendientevo)
	{
		System.out.println("guardarPendiente en AdministradorPendienteBean");
		
		Pendiente pendiente = new Pendiente();
		pendiente.setVO(pendientevo);
		
		System.out.println("Se hara el merge");
		em.merge(pendiente);
		
		System.out.println("Se persistio pendiente en database");
	}

	@SuppressWarnings("unchecked")
	public PendienteVO obtenerPendiente(int codigoArticulo, int codigoTienda)
	{
		System.out.println("obtenerPendiente en AdministradorPendienteBean");

		// Busca pendiente en database
		Pendiente pendiente=null;
		List list=null;
		
		ArticuloVO articulovo;
		TiendaVO tiendavo;
		Articulo articulo;
		Tienda tienda;
		
		list=em.createQuery("select p from Pendiente as p where p.articulo.codigo=:codart and p.tienda.codigo=:codtienda")
							.setParameter("codart", codigoArticulo)
							.setParameter("codtienda", codigoTienda)
							.getResultList();
		if(list.size()!=0)
		{
			pendiente=(Pendiente)list.get(0);
		}
		
		System.out.println("Se busco pendiente en database");
		if(pendiente!=null)
		{
			System.out.println("Pendiente: codigoArticulo=" + (pendiente.getArticulo()).getCodigo() +
							   ", codigoTienda=" + (pendiente.getTienda()).getCodigo());
			
			System.out.println("Devuelve un Pendiente que ya existia");
			return pendiente.getVO();
		}
		else
		{
			System.out.println("Pendiente no existia");
			
			getAdministradorArticulo();
			getAdministradorTienda();
			
			pendiente=new Pendiente();

			articulovo=administradorArticulo.obtenerArticulo(codigoArticulo);
			System.out.println("Obtuvo el Articulo");
			
			articulo=new Articulo();
			articulo.setVO(articulovo);
			pendiente.setArticulo(articulo);
			
			tiendavo=administradorTienda.obtenerTienda(codigoTienda);
			System.out.println("Obtuvo la Tienda");
			
			tienda=new Tienda();
			tienda.setVO(tiendavo);
			pendiente.setTienda(tienda);

			pendiente.setAEnviarATienda(0);
			pendiente.setAPedirAFabrica(0);
			pendiente.setALlegarDeFabricaYEnviar(0);
			pendiente.setALlegarDeFabrica(0);
			
			em.persist(pendiente);
			System.out.println("Devuelve un Pendiente que se ha creado");
			return pendiente.getVO();
		}
	}
	
	@SuppressWarnings("unchecked")
	public Vector obtenerPendientes()
	{
		List list=null;
		Vector listvo=new Vector();
		Pendiente pendiente;
		
		list=em.createQuery("select p from Pendiente as p")
							.getResultList();

		if(list.size()==0)
		{
			return listvo;
		}
		
		for(int i=0;i<list.size();i++)
		{
			pendiente=(Pendiente)list.get(i);
			listvo.add(pendiente.getVO());
		}

		System.out.println("Obtiene todos los pendientes desde el Bean de AdministradorPendiente");
		return listvo;
	}

	@SuppressWarnings("unchecked")
	public void registrarEnvioATienda()
	{
		System.out.println("registrarEnvioATienda en AdministradorPendienteBean");

		List list=null;
		Pendiente pendiente;
		RegistroEnvio registroenvio;
		
		getAdministradorRegistroEnvios();
		
		list=em.createQuery("select p from Pendiente as p")
							.getResultList();
		
		if(list.size()!=0)
		{
			System.out.println("Se obtuvo lista de pendientes");
			registroenvio=new RegistroEnvio();
			
			for(int i=0;i<list.size();i++)
			{
				pendiente=(Pendiente) list.get(i);
				
				if(pendiente.getAEnviarATienda()>0)
				{
					ArticuloEnviado articuloenviado=new ArticuloEnviado();
					
					Articulo articulo=pendiente.getArticulo();
					articuloenviado.setCodigoArticulo(articulo.getCodigo());
					
					Tienda tienda=pendiente.getTienda();
					articuloenviado.setCodigoTienda(tienda.getCodigo());
					
					articuloenviado.setAEnviarATienda(pendiente.getAEnviarATienda());
					articuloenviado.setALlegarDeFabrica(pendiente.getALlegarDeFabricaYEnviar());
					articuloenviado.setAPedirDeFabrica(pendiente.getAPedirAFabrica());
					
					registroenvio.agregarArticuloEnviado(articuloenviado);

					pendiente.setAEnviarATienda(0);
					em.merge(pendiente);
				}
			}
			
			administradorRegistroEnvios.registrarEnvio(registroenvio);
		}
		
		System.out.println("registrarEnvioATienda en AdministradorPendienteBean completo");
	}
	
	@SuppressWarnings("unchecked")
	public void registrarAPedirAFabrica()
	{
		System.out.println("registrarAPedirAFabrica en AdministradorPendienteBean");

		List list=null;
		Pendiente pendiente;
		RegistroFabricacion registrofabricacion;
		int existenteALlegarDeFabricaYEnviar;
		int existenteALlegarDeFabrica;
		int apedir;
		
		getAdministradorRegistroFabricacion();
		
		list=em.createQuery("select p from Pendiente as p")
							.getResultList();
		
		if(list.size()!=0)
		{
			System.out.println("Se obtuvo lista de pendientes");
			registrofabricacion=new RegistroFabricacion();
			
			for(int i=0;i<list.size();i++)
			{
				pendiente=(Pendiente) list.get(i);
				
				if(pendiente.getAPedirAFabrica()>0)
				{
					ArticuloAFabricar articuloafabricar=new ArticuloAFabricar();
					
					Articulo articulo=pendiente.getArticulo();
					articuloafabricar.setCodigoArticulo(articulo.getCodigo());
					
					Tienda tienda=pendiente.getTienda();
					articuloafabricar.setCodigoTienda(tienda.getCodigo());
					
					articuloafabricar.setAEnviarATienda(pendiente.getAEnviarATienda());
					articuloafabricar.setALlegarDeFabricaYEnviar(pendiente.getALlegarDeFabricaYEnviar());
					articuloafabricar.setALlegarDeFabrica(pendiente.getALlegarDeFabrica());
					articuloafabricar.setAPedirDeFabrica(pendiente.getAPedirAFabrica()*2);
					
					registrofabricacion.agregarArticuloAFabricar(articuloafabricar);

					existenteALlegarDeFabricaYEnviar=pendiente.getALlegarDeFabricaYEnviar();
					existenteALlegarDeFabrica=pendiente.getALlegarDeFabrica();
					apedir=pendiente.getAPedirAFabrica();
					
					pendiente.setAPedirAFabrica(0);
					pendiente.setALlegarDeFabricaYEnviar(existenteALlegarDeFabricaYEnviar+apedir);
					pendiente.setALlegarDeFabrica(existenteALlegarDeFabrica+apedir*2);
					
					em.merge(pendiente);
				}
			}
			
			administradorRegistroFabricacion.registrarFabricacion(registrofabricacion);
		}
		
		System.out.println("registrarAPedirAFabrica en AdministradorPendienteBean completo");
	}

	@SuppressWarnings("unchecked")
	public int enviarReposicionYPoneAEnviar(ArticuloVO articulo)
	{
		System.out.println("enviarReposicion en AdministradorPendienteBean");
		
		getAdministradorRegistroReposicion();
		administradorRegistroReposicion.registrarReposicion(articulo);
		
		Vector pendientes;
		int cantidad=articulo.getStock();
		Pendiente pendiente;
		PendienteVO pendientevo;
		int existente;
		
		pendientes=this.obtenerPendientesConArticulo(articulo);
		if(pendientes.size()==0)
		{
			return cantidad;
		}

		System.out.println("Despacha articulos en los pendientes");
		for(int i=0;i<pendientes.size();i++)
		{
			pendientevo=(PendienteVO)pendientes.get(i);
			
			if(pendientevo.getALlegarDeFabricaYEnviar()!=0)
			{
				if(cantidad<=pendientevo.getALlegarDeFabricaYEnviar())
				{
					existente=pendientevo.getAEnviarATienda();
					pendientevo.setAEnviarATienda(existente+cantidad);
					
					existente=pendientevo.getALlegarDeFabricaYEnviar();
					pendientevo.setALlegarDeFabricaYEnviar(existente-cantidad);
					
					existente=pendientevo.getALlegarDeFabrica();
					pendientevo.setALlegarDeFabrica(existente-cantidad);
					if(pendientevo.getALlegarDeFabrica()<0)
					{
						pendientevo.setALlegarDeFabrica(0);
					}
					
					pendiente=new Pendiente();
					pendiente.setVO(pendientevo);
					em.merge(pendiente);
					
					return 0;
				}
				else
				{
					existente=pendientevo.getAEnviarATienda();
					pendientevo.setAEnviarATienda(existente+pendientevo.getALlegarDeFabricaYEnviar());
					
					cantidad=cantidad-pendientevo.getALlegarDeFabricaYEnviar();
					
					existente=pendientevo.getALlegarDeFabrica();
					pendientevo.setALlegarDeFabrica(existente-pendientevo.getALlegarDeFabricaYEnviar());
					if(pendientevo.getALlegarDeFabrica()<0)
					{
						pendientevo.setALlegarDeFabrica(0);
					}
					
					pendientevo.setALlegarDeFabricaYEnviar(0);
					
					pendiente=new Pendiente();
					pendiente.setVO(pendientevo);
					em.merge(pendiente);
				}
			}
		}

		System.out.println("enviarReposicion en AdministradorPendienteBean completa");
		return cantidad;
	}
	
	@SuppressWarnings("unchecked")
	public Vector obtenerPendientesConArticulo(ArticuloVO articulovo)
	{
		List list=null;
		Vector listvo=new Vector();
		Pendiente pendiente;
		
		list=em.createQuery("select p from Pendiente as p where p.articulo.codigo=:codart")
							.setParameter("codart", articulovo.getCodigo())
							.getResultList();

		if(list.size()==0)
		{
			return listvo;
		}
			
		for(int i=0;i<list.size();i++)
		{
			pendiente=(Pendiente)list.get(i);
			listvo.add(pendiente.getVO());
		}

		System.out.println("Obtiene pendientes con el mismo articulo desde el Bean de AdministradorPendiente");
		return listvo;
	}
	
	@SuppressWarnings("unchecked")
	public Vector obtenerPendientesConTienda(TiendaVO tiendavo)
	{
		List list=null;
		Vector listvo=new Vector();
		Pendiente pendiente;
		
		list=em.createQuery("select p from Pendiente as p where p.tienda.codigo=:codtienda")
							.setParameter("codtienda", tiendavo.getCodigo())
							.getResultList();

		if(list.size()==0)
		{
			return listvo;
		}
			
		for(int i=0;i<list.size();i++)
		{
			pendiente=(Pendiente)list.get(i);
			listvo.add(pendiente.getVO());
		}

		System.out.println("Obtiene pendientes con la misma tienda desde el Bean de AdministradorPendiente");
		return listvo;
	}

	@SuppressWarnings("unchecked")
	public void enviarReposicion(ArticuloVO articulo, int astock)
	{
		int cantidad=astock;
		Vector pendientes;
		PendienteVO pendientevo;
		Pendiente pendiente;
		int existente;
		
		pendientes=this.obtenerPendientesConArticulo(articulo);
		if(pendientes.size()==0)
		{
			return;
		}

		System.out.println("Cancela articulos a llegar");
		for(int i=0;i<pendientes.size();i++)
		{
			pendientevo=(PendienteVO)pendientes.get(i);
			
			if(pendientevo.getALlegarDeFabrica()!=0)
			{
				if(cantidad<=pendientevo.getALlegarDeFabrica())
				{
					existente=pendientevo.getALlegarDeFabrica();
					pendientevo.setALlegarDeFabrica(existente-cantidad);
					if(pendientevo.getALlegarDeFabrica()<0)
					{
						pendientevo.setALlegarDeFabrica(0);
					}
					
					pendiente=new Pendiente();
					pendiente.setVO(pendientevo);
					em.merge(pendiente);
					
					return;
				}
				else
				{
					cantidad=cantidad-pendientevo.getALlegarDeFabrica();
					
					pendientevo.setALlegarDeFabrica(0);
					
					pendiente=new Pendiente();
					pendiente.setVO(pendientevo);
					em.merge(pendiente);
				}
			}
		}
	}
}
